/*
 * Created by JFormDesigner on Mon Sep 06 09:58:25 CST 2021
 */

package com.minelx.woods.pc.form;

import java.awt.*;
import java.awt.event.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.List;
import java.util.regex.Pattern;
import javax.swing.*;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.minelx.httpclient.core.request.IResponse;
import com.minelx.sqlstructures.common.Files;
import com.minelx.woods.pc.form.dialog.SelectPid;
import com.minelx.woods.pc.form.values.VariantValues;
import com.minelx.woods.pc.service.ReviewService;
import com.minelx.woods.pc.service.WoodsSession;
import com.minelx.woods.pc.service.mapper.ReviewRequestMapper;

import static com.alibaba.fastjson.JSON.toJSONString;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toMap;
import static javax.swing.JOptionPane.ERROR_MESSAGE;
import static javax.swing.JOptionPane.PLAIN_MESSAGE;

/**
 * @author aaa
 */
public class PostReviewForm extends JFrame {
	public static void main(String[] args) {
		WoodsSession session = new WoodsSession("name", "password");
		new PostReviewForm(session.reviewService()).setVisible(true);
	}

	private final ReviewService reviewService;

	private final JSONObject sourceMappings;

	private final DefaultComboBoxModel<String> sourceTypeModel;

	private final DefaultListModel<String> collectionsModel;

	private final DefaultListModel<VariantValues> variantCollectionsModel;

	public PostReviewForm(ReviewService reviewService) {
		initComponents();
		this.reviewService = reviewService;

		sourceMappings = JSON.parseObject(Files.toString("/mappings/major_sql_variables_mapping.json"));

		// prepare data model
		collectionsModel = new DefaultListModel<>();
		variantCollectionsModel = new DefaultListModel<>();
		sourceTypeModel = new DefaultComboBoxModel<>(sourceMappings.keySet().toArray(String[]::new));

		sourceTypeComboBox.setModel(sourceTypeModel);
	}

	private void collectionsActionPerformed(ActionEvent e) {
		new AddingCollectionsDialog(this, collectionsModel).setVisible(true);
	}

	private void variantCollectionsActionPerformed(ActionEvent e) {
		new AddingVariantCollectionsDialog(this, variantCollectionsModel).setVisible(true);
	}

	private void commitButtonActionPerformed(ActionEvent e) {
		String sourceType = sourceTypeModel.getElementAt(sourceTypeComboBox.getSelectedIndex());//memberIds或者地市之类
		try {
			IResponse response = reviewService.postReview(sourceType,
					JOptionPane.showInputDialog(null, "审核名称: "),
					// FIXME 2021/9/17  wait for me!!!      审核人员信息 在Server 识别
					List.of("DEF_SUBMITTER"),
					inputVariables(sourceType),
					toStringArray(collectionsModel.toArray()),
					stream(variantCollectionsModel.toArray())
							.map(item -> ((VariantValues) item))
							.toArray(VariantValues[]::new));
			String responseText = response.contentAsText(StandardCharsets.UTF_8);
			System.out.println("responseText = " + responseText);
			JSONObject responseJSON = JSON.parseObject(responseText);
			if (responseJSON.containsKey("error")) { // response error
				JOptionPane.showMessageDialog(this, "error while fetching response: " + responseJSON.getString("error"), "错误", ERROR_MESSAGE);
			} else {
				JOptionPane.showMessageDialog(this, responseJSON.toJSONString(), "消息", PLAIN_MESSAGE);
			}
		} catch (IllegalStateException exception) {
			System.out.println(exception.getMessage());
			JOptionPane.showMessageDialog(this, "请求出现了未知异常可能是请求超时！！");
		}
	}

	private JSONObject inputVariables(String sourceType) {
		JSONArray variables = sourceMappings.getJSONArray(sourceType);
		Map<String, Object> result = variables
				.toJavaList(JSONObject.class).stream()
				.map(mapping -> mapping.getString("name")) // FIXME 2021/9/7  wait for me!!!     variable type is ignored
				.collect(toMap(
						name -> name,
						this::convertToValues
				));
		return new JSONObject(result);
	}

	private void initComponents() {
		// JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
		label2 = new JLabel();
		sourceTypeComboBox = new JComboBox<>();
		label4 = new JLabel();
		collectionsButton = new JButton();
		variantCollectionsButton = new JButton();
		commitButton = new JButton();

		//======== this ========
		setTitle("\u63d0\u4ea4\u5ba1\u6838");
		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		var contentPane = getContentPane();
		contentPane.setLayout(null);

		//---- label2 ----
		label2.setText("\u8fc7\u6ee4\u65b9\u5f0f: ");
		label2.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 26));
		contentPane.add(label2);
		label2.setBounds(66, 35, 126, 60);
		contentPane.add(sourceTypeComboBox);
		sourceTypeComboBox.setBounds(192, 48, 164, sourceTypeComboBox.getPreferredSize().height);

		//---- label4 ----
		label4.setText("\u6536\u96c6: ");
		label4.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 26));
		contentPane.add(label4);
		label4.setBounds(65, 195, 75, 60);

		//---- collectionsButton ----
		collectionsButton.setText("\u666e\u901a\u5b57\u6bb5");
		collectionsButton.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 24));
		collectionsButton.addActionListener(e -> collectionsActionPerformed(e));
		contentPane.add(collectionsButton);
		collectionsButton.setBounds(new Rectangle(new Point(150, 210), collectionsButton.getPreferredSize()));

		//---- variantCollectionsButton ----
		variantCollectionsButton.setText("\u53c2\u6570\u5b57\u6bb5");
		variantCollectionsButton.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 24));
		variantCollectionsButton.addActionListener(e -> variantCollectionsActionPerformed(e));
		contentPane.add(variantCollectionsButton);
		variantCollectionsButton.setBounds(new Rectangle(new Point(150, 270), variantCollectionsButton.getPreferredSize()));

		//---- commitButton ----
		commitButton.setText("\u63d0\u4ea4");
		commitButton.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 24));
		commitButton.addActionListener(e -> commitButtonActionPerformed(e));
		contentPane.add(commitButton);
		commitButton.setBounds(new Rectangle(new Point(315, 422), commitButton.getPreferredSize()));

		{
			// compute preferred size
			Dimension preferredSize = new Dimension();
			for(int i = 0; i < contentPane.getComponentCount(); i++) {
				Rectangle bounds = contentPane.getComponent(i).getBounds();
				preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
				preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
			}
			Insets insets = contentPane.getInsets();
			preferredSize.width += insets.right;
			preferredSize.height += insets.bottom;
			contentPane.setMinimumSize(preferredSize);
			contentPane.setPreferredSize(preferredSize);
		}
		setSize(435, 515);
		setLocationRelativeTo(getOwner());
		// JFormDesigner - End of component initialization  //GEN-END:initComponents
	}

	// JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables
	private JLabel label2;
	private JComboBox<String> sourceTypeComboBox;
	private JLabel label4;
	private JButton collectionsButton;
	private JButton variantCollectionsButton;
	private JButton commitButton;
	// JFormDesigner - End of variables declaration  //GEN-END:variables

	private static String[] toStringArray(Object[] objects) {
		return stream(objects).map(String::valueOf).toArray(String[]::new);
	}

	public static long[] preprocessMemberIds(String memberIdsAsText) {
		if (memberIdsAsText == null) {
			throw new RuntimeException("user onclick cancel!");
		}
		memberIdsAsText = memberIdsAsText.replace(" ", ",");
		return Arrays.stream(memberIdsAsText.split(","))
				.mapToLong(Long::parseLong)
				.map(item -> {
					if (item > 5000500000L) {
						return item - 5000500000L;
					}
					if (item > 1000500000) {
						return item - 1000500000;
					}
					return item;
				})
				.toArray();
	}

	private Object convertToValues(String name) {
		if (name.equals("memberIds")) {
			return preprocessMemberIds(JOptionPane.showInputDialog(this, name));
		} else if (name.equals("proxies")) {
			SelectPid selectPid = new SelectPid(this);
			selectPid.setVisible(true);
			return selectPid.getSelectedProxies();
		} else if (name.equals("wechatIds") || name.equals("hlbMerchantIds")) {
			return preprocessStrIds(JOptionPane.showInputDialog(this, name), name);
		}
		throw new RuntimeException("illegal name: " + name);
	}

	private Object preprocessStrIds(String strIdsAsText, String name) {
		isCancelOnclick(strIdsAsText);
		boolean matches = Pattern.compile("([a-zA-Z]*\\d+\\s*)+").matcher(strIdsAsText).matches();
		while (!matches) {
			JOptionPane.showMessageDialog(PostReviewForm.this, "输入的编号存在特殊字符");
			strIdsAsText = JOptionPane.showInputDialog(this, name);
			isCancelOnclick(strIdsAsText);
			matches = Pattern.compile("([a-zA-Z]*\\d+,*)+").matcher(strIdsAsText).matches();
		}

		strIdsAsText = strIdsAsText.replace(" ", ",");
		return stream(strIdsAsText.split(","))
				.map(item -> "'" + item + "'")
				.toArray();
	}

	private void isCancelOnclick(String strIdsAsText) {
		if (strIdsAsText == null) {
			throw new RuntimeException("user onclick cancel！");
		}
	}
}
